Titre

------------------------------------- Chapitre VIII - Cryptographie -------------------------------------

Cryptographie symétrique : un exemple de Blowfish - 2/4

 

Trouver un serial valide :

On lance le logiciel, on a la page d'accueil suivante :

Unregistered

Le logiciel demande un couple name / serial :

Unregistered1

On va maintenant taper le couple email address (toto@gmail.com) / license code (0123456789).
On obtient alors l'erreur suivante :

Unregistered1

En posant un breakpoint sur l'API MessageBoxA, on remonte facilement à l'appel dans mfc42.dll (encapsulation de l'API) :

Unregistered3

puis à l'appel dans l'exécutable :

Serial0

On voit donc bien que le paramètre (affecté à EAX) que l'on récupère en sortie de fonction doit être inférieur à 1869Fh sans être nul pour autant...
A quoi correspond ce dword affecté à EAX ?

Essayons d'abord de retrouver les différentes fonctions de Blowfish.

Phase d'extension (ou initialisation) :

En traçant jusqu'en 00416537, on finit par avoir ceci dans la pile :

Serial2

Ça y est, on a notre clé privée !

Note : Attention, la clef privée peut ne pas être une chaîne.
On en a un exemple avec Drive Power Manager v1.10 :

Serial40

On peut commenter le code pour le rendre plus compréhensible :

Serial3

La taille de la clef (19h) a été déterminée par :

00416516 |. E8 81150200 CALL <JMP.&MFC42.#537>

Cet appel encapsule en fait l'API lstrlenA :

Serial4

En traçant dans Blowfish_Init( ), on retombe sur l'initialisation des S-Boxes et du tableau P, qui sont des tableaux de valeurs constantes...
Les valeurs dans les S-Boxes sont tirées du nombre Pi exprimé en hexadécimal.
La routine suivante recopie en mémoire les 4 S-Boxes :

Serial5

S-Box : 256 éléments (DWORDs)

Serial6

Le premier élément de la 1ère S-Box est :

D1310BA6h

Il est notamment utilisé pour reconnaître la présence de Blowfish.
Il peut cependant arriver que certains programmes implémentent des versions modifiées de cet algorithme.
Ainsi, certains outils comme PEiD ou RDG peuvent échouer dans la détection, donc faites attention !

Voici, ensuite, la routine, qui effectue un XOR entre le P-Array et la clef choisie :

Serial7

Si la taille de la clef (en bits) devient inférieur à l'index dans le P-array (18*32 bytes), on reprend le début de la clef...

P-array : 18 éléments (DWORDs)

Serial8

Le premier élément du tableau P est :

243F6A88h

Voici le context (qui comprend le tableau P et les 4 S-Boxes) avant l'exécution de cette routine :

Serial9

En vert, on a le 1er élément de la 1ère S-Box.

Le context devient après l'exécution de cette routine :

Serial10

Dans la phase d'extension d'initialisation, on trouve des appels à la fonction de chiffrement ( Blowfish_encrypt ( ) ).
Cette source en C le confirme :

Serial11

Voici les 2 appels à la fonction Blowfish_encrypt ( ) dans Blowfish_Initialization ( ) :

Serial12

Dans Blowfish_Initialization ( ), le premier chiffrement par la fonction Blowfish_encrypt ( ), concerne le Tableau P, le deuxième, les 4 S-Boxes.
Il faut donc faire attention à ne pas confondre les appels à la fonction Blowfish_encrypt ( ) dans l'initialisation à un éventuel autre appel, qui, lui concernerait le chiffrement des données du serial.

Voici cette fonction Blowfish_encrypt ( ) :

Serial13

Ici, on voit le réseau de Feistel à l'oeuvre ! On est au coeur de la fonction Blowfish_encrypt ( ).
On observe la valeur 10h (qui correspond aux 16 tours effectuées).
Le processus entier se base sur des opérations XOR, ces XORs se produisent entre deux données de 32 bits chacune.

On peut également remarquer que la fonction Blowfish_encrypt ( ) est appelée uniquement deux fois (par la fonction d'initialisation).

Serial14

Ceci peut nous laisser émettre l'hypothèse que le serial contient des données, qui seront déchiffrées par Blowfish (la fonction Blowfish_decrypt ( ) ).
Le reverser devra donc chiffrer pour retrouver le bon serial.
Dans la plupart des cas, c'est cependant l'inverse, le programme utilise la fonction Blowfish_Init ( ) et la fonction Blowfish_encrypt ( ).
Le reverser n'aura donc qu'à connaître la clef secrète et à implémenter une fonction de déchiffrement...

Voici la fonction GetByte (X,Y), appelée par Blowfish_encrypt ( ) :

Serial15

La fonction de déchiffrement est appelée deux fois dans l'initialisation et s'applique au Tableau P, puis aux 4 S-Boxes.
La fonction Blowfish_Init( ) s'achève alors. On peut donc passer à la phase suivante...

 

 

Precedent        Sommaire        Suivant